package com.correction.servlet;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.Part;

import com.correction.classes.Utilisateur;
import com.correction.dao.UtilisateurDAO;
import com.correction.database.Database;
import com.correction.database.MySqlDataSource;

@WebServlet("/upload")
@MultipartConfig
public class Controler extends HttpServlet {

	private static final long serialVersionUID = 4882286010437359179L;
	private final Logger LOGGER = Logger.getLogger(Controler.class
			.getCanonicalName());
	private Database db;

	public void init() throws ServletException {
		db = new Database(new MySqlDataSource("correction_exam", "localhost",
				"root", ""));
	}

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response);
	}

	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		HttpSession session = request.getSession(true);
		String action = request.getParameter("action");

		if (action.equals("valider")) {
			UtilisateurDAO utilisateurDAO = new UtilisateurDAO(db);
			String nom = request.getParameter("nom");
			String prenom = request.getParameter("prenom");
			String mail = request.getParameter("mail");
			String pseudo = request.getParameter("pseudo");
			String pwd = request.getParameter("pwd");
			if (!nom.equals("") && !prenom.equals("") && !mail.equals("")
					&& !pwd.equals("") && !pseudo.equals("")) {
				Utilisateur utilisateur = new Utilisateur(nom, prenom, mail,
						pseudo, pwd);
				utilisateurDAO.add(utilisateur);
				getServletContext().getRequestDispatcher("/Index.html")
						.forward(request, response);
			}
		} else if (action.equals("connecter")) {
			UtilisateurDAO utilisateurDAO = new UtilisateurDAO(db);
			String pseudo = request.getParameter("pseudo");
			String pwd = request.getParameter("pwd");
			if (!pseudo.equals("") && !pwd.equals("")) {
				Utilisateur utilisateur = utilisateurDAO.getUtilisateur(pseudo,
						pwd);
				if (utilisateur != null) {

					System.out.println("connexion reussie");
					System.out.println(utilisateur);
					System.out.println("Droit d'access : "
							+ utilisateur.getType());
					getServletContext().getRequestDispatcher("/Upload.html")
							.forward(request, response);
				} else {
					System.out.println("connexion failed");
					getServletContext().getRequestDispatcher("/Index.html")
					.forward(request, response);
				}
			}
		} else if (action.equals("upload")) {
			response.setContentType("text/html;charset=UTF-8");

			// Create path components to save the file
			final String path = request.getParameter("destination");
			System.out.println("destination " + path);
			final Part filePart = request.getPart("file");
			final String fileName = getFileName(filePart);

			OutputStream out = null;
			InputStream filecontent = null;
			final PrintWriter writer = response.getWriter();

			try {
				out = new FileOutputStream(new File(path + File.separator + fileName));
				
				filecontent = filePart.getInputStream();
				int read = 0;
				final byte[] bytes = new byte[1024];
				String direc = null;
				while ((read = filecontent.read(bytes)) != -1) {
					String myString = new String(bytes);
					if (myString.contains("package")) {
						myString = myString.replace("package", "");
						myString = myString.substring(0, myString.indexOf(";"));
						direc = myString;
					}
					out.write(bytes, 0, read);
				}
				/* Compile and execute */

				Runtime runtime = Runtime.getRuntime();
				final Process process1 = runtime.exec("javac -d " + path + " "
						+ path + File.separator + fileName);
				String[] parts = fileName.split("\\.");
				final Process process2 = runtime.exec("java -cp " + path + " "
						+ direc + "." + parts[0]);

				// Consommation de la sortie standard de l'application externe
				// dans un Thread separe
				new Thread() {
					public void run() {
						try {
							BufferedReader reader = new BufferedReader(
									new InputStreamReader(
											process2.getInputStream()));
							String line = "";
							String textFile = "";
							try {
								while ((line = reader.readLine()) != null) {
									textFile = textFile + line;
								}
								FileWriter fw = new FileWriter(
										path+"\\File-Log.txt");
								BufferedWriter bw = new BufferedWriter(fw);
								bw.write(textFile);
								bw.close();
							} finally {
								reader.close();
							}
						} catch (IOException ioe) {
							ioe.printStackTrace();
						}
					}
				}.start();

				// Consommation de la sortie d'erreur de l'application externe
				// dans un Thread separe
				new Thread() {
					public void run() {
						try {
							BufferedReader reader = new BufferedReader(
									new InputStreamReader(
											process2.getErrorStream()));
							String line = "";
							try {
								while ((line = reader.readLine()) != null) {
									System.out.println("Error: " + line);
								}
							} finally {
								reader.close();
							}
						} catch (IOException ioe) {
							ioe.printStackTrace();
						}
					}
				}.start();
				writer.println("New file " + fileName + " created at " + path);
				LOGGER.log(Level.INFO, "File{0}being uploaded to {1}",
						new Object[] { fileName, path });
			} catch (FileNotFoundException fne) {
				writer.println("You either did not specify a file to upload or are "
						+ "trying to upload a file to a protected or nonexistent "
						+ "location.");
				writer.println("<br/> ERROR: " + fne.getMessage());

				LOGGER.log(Level.SEVERE,
						"Problems during file upload. Error: {0}",
						new Object[] { fne.getMessage() });
			} finally {
				if (out != null) {
					out.close();
				}
				if (filecontent != null) {
					filecontent.close();
				}
				if (writer != null) {
					writer.close();
				}
			}
		}
	}

	private String getFileName(final Part part) {
		final String partHeader = part.getHeader("content-disposition");
		LOGGER.log(Level.INFO, "Part Header = {0}", partHeader);
		for (String content : part.getHeader("content-disposition").split(";")) {
			if (content.trim().startsWith("filename")) {
				return content.substring(content.indexOf('=') + 1).trim()
						.replace("\"", "");
			}
		}
		return null;
	}
}